
// <copyright file="GeneralSqlServerHelper.cs" company="Subhadra Software Solutions">
//   
// </copyright>
// <summary>
//   The general sql server helper.
// </summary>

namespace SubhadraSolutions.Sharp.Utils.Data.SqlServer
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    using System.Data.SqlTypes;

    using SubhadraSolutions.Sharp.Utils.Data.Sync;
    using SubhadraSolutions.Sharp.Utils.Properties;

    /// <summary>
    /// The general sql server helper.
    /// </summary>
    public static class GeneralSqlServerHelper
    {
        #region Public Methods and Operators

		/// <summary>
        ///     Gets the SQL server allowed maximum date time.
        /// </summary>
        /// <value>
        ///     The SQL server allowed maximum date time.
        /// </value>
        public static DateTime SqlServerAllowedMaxDateTime
        {
            get
            {
                return (DateTime)SqlDateTime.MaxValue;
            }
        }

        /// <summary>
        ///     Gets the SQL server allowed minimum date time.
        /// </summary>
        /// <value>
        ///     The SQL server allowed minimum date time.
        /// </value>
        public static DateTime SqlServerAllowedMinDateTime
        {
            get
            {
                return (DateTime)SqlDateTime.MinValue;
            }
        }

        /// <summary>
        /// Converts to the SQL server allowed date time.
        /// </summary>
        /// <param name="dateTime">
        /// The date time.
        /// </param>
        /// <returns>
        /// The <see cref="DateTime"/>.
        /// </returns>
        public static DateTime ToSqlServerAllowedDateTime(DateTime dateTime)
        {
            if (dateTime < SqlServerAllowedMinDateTime)
            {
                return SqlServerAllowedMinDateTime;
            }

            if (dateTime > SqlServerAllowedMaxDateTime)
            {
                return SqlServerAllowedMaxDateTime;
            }

            return dateTime;
        }

        /// <summary>
        /// The get table dependency order.
        /// </summary>
        /// <param name="connection">
        /// The connection.
        /// </param>
        /// <param name="isOrdinaryDesc">
        /// The is ordinary desc.
        /// </param>
        /// <returns>
        /// The <see cref="List{T}"/>.
        /// </returns>
        public static List<string> GetTableDependencyOrder(SqlConnection connection, bool isOrdinaryDesc)
        {
            string s = " ORDER BY Ordinal" + (isOrdinaryDesc ? " DESC" : null) + ", TableName";
            using (IDbCommand command = connection.CreateCommand())
            {
                command.CommandText = Resources.SQLSERVER_TABLE_DEPENDENCY_ORDER_COMMAND + s;
                using (IDataReader reader = command.ExecuteReader())
                {
                    var list = new List<string>();
                    while (reader.Read())
                    {
                        list.Add((string)reader[0]);
                    }

                    return list;
                }
            }
        }

        /// <summary>
        /// The get table dependency order.
        /// </summary>
        /// <param name="connectionString">
        /// The connection string.
        /// </param>
        /// <param name="isOrdinaryDesc">
        /// The is ordinary desc.
        /// </param>
        /// <returns>
        /// The <see cref="List{T}"/>.
        /// </returns>
        public static List<string> GetTableDependencyOrder(string connectionString, bool isOrdinaryDesc)
        {
            var connection = new SqlConnection(connectionString);
            using (connection)
            {
                connection.Open();
                return GetTableDependencyOrder(connection, isOrdinaryDesc);
            }
        }

        /// <summary>
        /// The import data.
        /// </summary>
        /// <param name="sourceConnectionString">
        /// The source connection string.
        /// </param>
        /// <param name="targetConnectionString">
        /// The target connection string.
        /// </param>
        /// <param name="truncateTargetTable">
        /// The truncate target table.
        /// </param>
        public static void ImportData(string sourceConnectionString, string targetConnectionString, bool truncateTargetTable)
        {
            List<string> tableNames = GetTableDependencyOrder(sourceConnectionString, true);
            importData(sourceConnectionString, targetConnectionString, true, tableNames, false);
        }

        /// <summary>
        /// The import data.
        /// </summary>
        /// <param name="sourceConnectionString">
        /// The source connection string.
        /// </param>
        /// <param name="targetConnectionString">
        /// The target connection string.
        /// </param>
        /// <param name="truncateTargetTable">
        /// The truncate target table.
        /// </param>
        /// <param name="tableNames">
        /// The table names.
        /// </param>
        public static void ImportData(string sourceConnectionString, string targetConnectionString, bool truncateTargetTable, IList<string> tableNames)
        {
            importData(sourceConnectionString, targetConnectionString, true, tableNames, true);
        }

        #endregion Public Methods and Operators

        #region Methods

        /// <summary>
        /// The import data.
        /// </summary>
        /// <param name="sourceConnectionString">
        /// The source connection string.
        /// </param>
        /// <param name="targetConnectionString">
        /// The target connection string.
        /// </param>
        /// <param name="truncateTargetTable">
        /// The truncate target table.
        /// </param>
        /// <param name="tableNames">
        /// The table names.
        /// </param>
        /// <param name="reorder">
        /// The reorder.
        /// </param>
        private static void importData(string sourceConnectionString, string targetConnectionString, bool truncateTargetTable, IList<string> tableNames, bool reorder)
        {
            IList<string> tables = tableNames;
            if (reorder)
            {
                tables = GetTableDependencyOrder(sourceConnectionString, true);
                for (int i = 0; i < tables.Count; i++)
                {
                    if (!tableNames.Contains(tables[i]))
                    {
                        tables.RemoveAt(i);
                        i--;
                    }
                }
            }

            DataImporter.ImportData(typeof(SqlConnection), sourceConnectionString, typeof(SqlConnection), targetConnectionString, BulkCopier.Instance, truncateTargetTable, tables);
        }

        #endregion Methods
    }
}